﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Windows.Forms;
using Newtonsoft.Json;
using QuTouTiaoAssist.Entity;

namespace QuTouTiaoAssist.Util
{
    /// <summary>
    /// 趣头条辅助工具
    /// </summary>
    class QttHelper
    {
        /// <summary>
        /// 设备号，15位
        /// </summary>
        private static string deviceCode = "864394010682476";

        public static readonly string DefaultUserAgent =
            "Mozilla/5.0 (Linux; Android 5.1; MX5 Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.124 Mobile Safari/537.36 qukan_android";

        public static Size DefaultQRCodeImageSize = new Size(442, 442);

        public const string DefaultApiHost = "http://api.1sapp.com/";

        /// <summary>
        /// 邀请二维码背景图url
        /// </summary>
        public static string InviteBgImageUrl = "http://h5ssl.1sapp.com/qukan/style/images/yq2_pic12.jpg";

        public static string RefreshDeviceCode()
        {
            var deviceCode = GenerateDeviceCode();
            SetDeviceCode(deviceCode);
            return deviceCode;
        }

        public static string GenerateDeviceCode()
        {
            string code = string.Empty;
            Random r = new Random((int)DateTime.Now.Ticks);
            for (int i = 0; i < 15; i++)
            {
                code += r.Next(0, 9) + "";
            }

            return code;
        }

        public static string GetDeviceCode()
        {
            if (deviceCode == null)
                GenerateDeviceCode();

            return deviceCode;
        }

        public static void SetDeviceCode(string code)
        {
            deviceCode = code;
            Log.Write("device修改为：" + code);
        }

        /// <summary>
        /// 绑定微信
        /// </summary>
        /// <param name="token"></param>
        /// <param name="wxOpenId"></param>
        /// <param name="avatarUrl"></param>
        /// <param name="nickName"></param>
        /// <param name="sex"></param>
        /// <returns></returns>
        public static QttResultInfo<QttBindWxResult> BindWx(string token, string wxOpenId, string avatarUrl, string nickName, int sex)
        {
            var pc = CreateParam2("001");
            pc.Add("avatar", avatarUrl);
            pc.Add("nickname", nickName);
            pc.Add("open_id", wxOpenId);
            pc.Add("sex", sex);
            pc.Add("token", token);
            pc.Add("sign", CalcSign(pc));

            return RequestPostText<QttResultInfo<QttBindWxResult>>(DefaultApiHost + "member/bindWx", pc);
        }

        /// <summary>
        /// 兑换商品
        /// </summary>
        /// <param name="token"></param>
        /// <param name="itemId">商品ID</param>
        /// <returns></returns>
        public static QttResultInfo<QttDataEmpty> ExchangeItem(string token, string itemId)
        {
            var pc = new Dictionary<string, object>();
            pc.Add("token", token);
            pc.Add("item_id", itemId);
            pc.Add("dtu", 200);

            return RequestPostText<QttResultInfo<QttDataEmpty>>
                (DefaultApiHost + "convert/applyConvert?_=" + 
                                GetCurrentUnixTimeInMillis(), pc);
        }

        /// <summary>
        /// 查询兑换记录
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static QttResultInfo<List<QttExchangeRecord>> GetExchangeRecords(string token)
        {
            var pc = CreateParam1("200");
            pc.Add("token", token);
            pc.Add("page", 1);
            pc.Add("max", 100);

            return RequestGetText<QttResultInfo<List<QttExchangeRecord>>>("convert/applyList", pc);
        }

        /// <summary>
        /// 找回密码
        /// </summary>
        /// <param name="smsCaptcha"></param>
        /// <param name="mobile"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static QttResultInfo<QttDataEmpty> FindPassword(string smsCaptcha, string mobile, string password)
        {
            var pc = CreateParam2("001");
            pc.Add("captcha", smsCaptcha);
            pc.Add("password", password);
            pc.Add("password2", password);
            pc.Add("telephone", mobile);
            pc.Add("sign", CalcSign(pc));

            return RequestPostText<QttResultInfo<QttDataEmpty>>(DefaultApiHost + "member/findPassword", pc);
        }

        /// <summary>
        /// 检查短信验证码是否正确
        /// </summary>
        /// <param name="smsCaptcha"></param>
        /// <param name="mobile"></param>
        /// <param name="useWay">1用于注册；2用于密码找回</param>
        public static QttResultInfo<QttDataEmpty> CheckSmsCaptcha(string smsCaptcha, string mobile, string useWay)
        {
            var pc = CreateParam2("001");
            pc.Add("captcha", smsCaptcha);
            pc.Add("telephone", mobile);
            pc.Add("use_way", useWay);
            pc.Add("sign", CalcSign(pc));

            return RequestPostText<QttResultInfo<QttDataEmpty>>(DefaultApiHost + "captcha/checkSmsCaptcha", pc);
        }

        /// <summary>
        /// 获取短信验证码（密码找回）
        /// </summary>
        /// <param name="mobile"></param>
        /// <param name="imgCaptcha"></param>
        /// <param name="imgCaptchaId"></param>
        public static QttResultInfo<QttDataEmpty> GetSmsCaptcha2(string mobile, string imgCaptcha, string imgCaptchaId)
        {
            var pc = CreateParam2("001");
            pc.Add("img_captcha", imgCaptcha);
            pc.Add("img_captcha_id", imgCaptchaId);
            pc.Add("telephone", mobile);
            pc.Add("use_way", "2");
            pc.Add("sign", CalcSign(pc));

            return RequestGetText<QttResultInfo<QttDataEmpty>>("captcha/getSmsCaptcha", pc);
        }

        /// <summary>
        /// 获取图片验证码（密码找回）
        /// </summary>
        public static QttResultInfo<QttImgCaptchaInfo> GetImgCaptcha2()
        {
            var pc = CreateParam2("001");
            pc.Add("sign", CalcSign(pc));

            return RequestGetText<QttResultInfo<QttImgCaptchaInfo>>("captcha/getImgCaptcha2", pc);
        }

        /// <summary>
        /// 获取推荐文章列表
        /// </summary>
        /// <returns></returns>
        public static List<QttArticleInfo> GetRecommandArticleList(string token)
        {
            var pc = CreateParam1("200");
            pc.Add("token", token);

            var str = RequestGetText("content/getRecommend", pc);
            var type = new
            {
                data = new
                {
                    data = new List<QttArticleInfo>()
                    {
                        new QttArticleInfo()
                    }
                }
            };
            var typeValue = JsonConvert.DeserializeAnonymousType(str, type);

            return typeValue.data.data;
        }

        /// <summary>
        /// 获取分享邀请地址
        /// </summary>
        /// <returns></returns>
        public static List<string> GetShareDomain(string token)
        {
            List<string> domains = new List<string>();

            var pc = CreateParam1("200");
            pc.Add("token", token);

            var str = RequestGetText("domain/getShareDomain", pc);
            Regex r = new Regex("\"([^\"]+)\"");
            MatchCollection mc = r.Matches(str);
            for (int i = 0; i < mc.Count; i++)
            {
                var matchStr = mc[i].Groups[1].Value;
                if (matchStr.Contains("html"))
                {
                    domains.Add(matchStr.Replace("\\/","/"));
                }
            }

            return domains;
        }

        /// <summary>
        /// 领取礼物
        /// </summary>
        /// <param name="token"></param>
        /// <param name="giftId"></param>
        /// <returns></returns>
        public static QttResultInfo<QttReceiveGiftInfo> ReceiveGift(string token, string giftId)
        {
            var pc = CreateParam2("100");
            pc.Add("gift_id", giftId);
            pc.Add("network", "WIFI");
            pc.Add("token", token);
            pc.Add("sign", CalcSign(pc));

            return RequestPostText<QttResultInfo<QttReceiveGiftInfo>>(DefaultApiHost + "mission/receiveGift", pc);
        }

       /// <summary>
        /// 查询可兑换的商品
       /// </summary>
       /// <param name="token"></param>
       /// <returns></returns>
        public static QttResultInfo<List<QttExchangeProduct>> GetExchangeProduct(string token)
        {
            var pc = CreateParam1("200");
            pc.Add("token", token);

            return RequestGetText<QttResultInfo<List<QttExchangeProduct>>>("convert/showList", pc);
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="token"></param>
        /// <param name="oldPwd"></param>
        /// <param name="newPwd"></param>
        /// <returns></returns>
        public static QttResultInfo<QttDataEmpty> ModifyPwd(string token, string oldPwd, string newPwd)
        {
            var pc = CreateParam2("001");
            pc.Add("old_password", oldPwd);
            pc.Add("password", newPwd);
            pc.Add("password2", newPwd);
            pc.Add("token", token);
            pc.Add("sign", CalcSign(pc));

            return RequestPostText<QttResultInfo<QttDataEmpty>>(DefaultApiHost + "member/modifyPassword", pc);
        }

        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="token"></param>
        /// <param name="nickName"></param>
        /// <param name="birth"></param>
        /// <returns></returns>
        public static QttResultInfo<QttDataEmpty> ModifyUserInfo(string token, string nickName, DateTime birth)
        {
            var pc = CreateParam2("001");
            pc.Add("nickname", nickName);
            pc.Add("birth", birth.ToString("yyyy-MM-dd"));
            pc.Add("token", token);
            pc.Add("sign", CalcSign(pc));

            return RequestPostText<QttResultInfo<QttDataEmpty>>(DefaultApiHost + "member/modify", pc);
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="mobile">手机号</param>
        /// <param name="pwd">密码</param>
        /// <returns></returns>
        public static QttResultInfo<QttLoginResult> Login(string mobile, string pwd)
        {
            var pc = CreateParam2("001");
            pc.Add("telephone", mobile);
            pc.Add("password", pwd);
            pc.Add("sign", CalcSign(pc));

            return RequestGetText<QttResultInfo<QttLoginResult>>("member/login", pc);
        }

        /// <summary>
        /// 获取频道列表
        /// </summary>
        /// <returns></returns>
        public static QttResultInfo<List<QttChannelInfo>> GetDefaultChannelList()
        {
            var pc = CreateParam2("001");
            pc.Add("sign", CalcSign(pc));

            return RequestGetText<QttResultInfo<List<QttChannelInfo>>>("content/getDefaultChannelList", pc);
        }

        /// <summary>
        /// 生成频道URL
        /// </summary>
        /// <param name="channelId"></param>
        /// <param name="pageNum"></param>
        /// <returns></returns>
        public static string GenArticleChannelUrl(int channelId, int pageNum)
        {
            var pc = CreateParam2("001");
            pc.Add("cid", channelId);
            pc.Add("content_type", "1,2,4");
            pc.Add("max_time", 0);
            pc.Add("op", 2);
            pc.Add("page", pageNum);
            pc.Add("show_time", 0);
            pc.Add("sign", CalcSign(pc));

            string url = string.Format("http://api.1sapp.com/{0}?", "content/getList");
            url += ParamDic2String(pc);

            return url;
        }

        /// <summary>
        /// 获取文章列表
        /// </summary>
        /// <param name="channelId">频道id</param>
        /// <param name="pageNum">页码</param>
        /// <returns></returns>
        public static List<QttArticleInfo> GetArticleList(int channelId, int pageNum)
        {
            var pc = CreateParam2("001");
            pc.Add("cid",channelId);
            pc.Add("content_type", "1,2,4");
            pc.Add("max_time", 0);
            pc.Add("op",2);
            pc.Add("page",pageNum);
            pc.Add("show_time",0);
            pc.Add("sign", CalcSign(pc)); 

            var str = RequestGetText("content/getList", pc);
            var type = new
            {
                data = new
                {
                    data = new List<QttArticleInfo>()
                    {
                        new QttArticleInfo()
                    }
                }
            };
            var typeValue = JsonConvert.DeserializeAnonymousType(str, type);

            return typeValue.data.data;
        }

        /// <summary>
        /// 生成参数
        /// </summary>
        /// <param name="dtu">dtu值</param>
        /// <returns></returns>
        private static Dictionary<string, object> CreateParam1(string dtu)
        {
            var dic = new Dictionary<string, object>();
            dic.Add("dtu", dtu);
            dic.Add("_", GetCurrentUnixTimeInMillis());

            return dic;
        }

        /// <summary>
        /// 生成参数
        /// </summary>
        /// <param name="dtu">dtu值</param>
        /// <returns></returns>
        private static Dictionary<string, object> CreateParam2(string dtu)
        {
            var dic = new Dictionary<string,object>();
            dic.Add("OSVersion","4.4.2");
            dic.Add("deviceCode", deviceCode);
            dic.Add("dtu",dtu);
            dic.Add("lat", 0.0);
            dic.Add("lon",0.0);
            dic.Add("version",10204);
            dic.Add("time", GetCurrentUnixTimeInMillis());

            return dic;
        }

        /// <summary>
        /// 计算sign值
        /// </summary>
        /// <param name="args">参数列表</param>
        /// <returns></returns>
        public static string CalcSign(Dictionary<string, object> args)
        {
            // 按key值进行排序，注：要完全按照ascii码值
            var orderedArgs = args.OrderBy(pair => pair.Key, new NonCultureStringComparer()).ToDictionary(
                pair => pair.Key, pair => pair.Value);

            // 拼接字符串并计算md5值
            StringBuilder builder = new StringBuilder();
            foreach (KeyValuePair<string, object> item in orderedArgs)
            {
                string key = item.Key;
                string value = item.Value == null ? "" : item.Value.ToString();
                builder.AppendFormat("{0}={1}&", key, value);
            }
            string combineStr = builder.ToString() + "key=txscP6NCs3U6AIgT";

            return CalcMd5(combineStr);
        }

        /// <summary>
        /// 计算MD5值
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string CalcMd5(string str)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            var bytes = md5.ComputeHash(System.Text.Encoding.GetEncoding("utf-8").GetBytes(str));

            return BitConverter.ToString(bytes).Replace("-", "").ToLower();
        }

        /// <summary>
        /// 获取邀请二维码图片
        /// </summary>
        /// <param name="inviteUrl">邀请地址</param>
        /// <param name="size">二维码尺寸</param>
        /// <returns></returns>
        public static Image GetInviteImage(string inviteUrl, Size size)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("url", inviteUrl);
            pc.Add("width", size.Width.ToString());
            pc.Add("height", size.Height.ToString());
            //pc.Add("width", "240");
            //pc.Add("height", "240");

            return RequestGetImage("qrcode/generate", pc);
        }

        /// <summary>
        /// 获取图片验证码（用于注册）
        /// </summary>
        /// <param name="mobile">手机号</param>
        /// <returns></returns>
        public static Image GetImgCaptcha(string mobile)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("dtu","200");
            pc.Add("telephone", mobile);
            pc.Add("use_way","1");
            pc.Add("_r" + new Random().NextDouble(), null);

            return RequestGetImage("captcha/getImgCaptcha", pc);
        }

        /// <summary>
        /// 获取短信验证码（用于注册）
        /// </summary>
        /// <param name="mobile">手机号</param>
        /// <param name="imgCaptcha">图片验证码</param>
        /// <returns></returns>
        public static QttResultInfo<QttDataEmpty> GetSmsCaptcha(string mobile, string imgCaptcha)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("telephone", mobile);
            pc.Add("use_way", "1");
            pc.Add("img_captcha", imgCaptcha);
            pc.Add("img_captcha_id", string.Empty);
            pc.Add("dtu", "200");
            pc.Add("_", GetCurrentUnixTimeInMillis().ToString());

            var respStr = RequestGetText("captcha/getSmsCaptcha", pc);
            var typeValue = JsonConvert.DeserializeObject<QttResultInfo<QttDataEmpty>>(respStr);

            return typeValue;
        }

        /// <summary>
        /// 注册用户
        /// </summary>
        /// <param name="mobile">手机号</param>
        /// <param name="password">密码</param>
        /// <param name="smsCaptcha">短信验证码</param>
        /// <param name="inviteCode">邀请码</param>
        /// <returns></returns>
        public static string Register(string mobile, string password, string smsCaptcha, string inviteCode)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("_", GetCurrentUnixTimeInMillis().ToString());
            pc.Add("captcha", smsCaptcha);
            pc.Add("dtu", 200);
            pc.Add("invite_code", inviteCode);
            pc.Add("is_web", 1);
            pc.Add("password", password);
            pc.Add("telephone", mobile);

            return RequestPostText(DefaultApiHost + "member/register", pc);
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="memberToken">用户token</param>
        /// <returns></returns>
        public static QttResultInfo<QttMemberInfo> GetMemberInfo(string memberToken)
        {
            var pc = CreateParam2("001");
            pc.Add("token", memberToken);
            pc.Add("sign", CalcSign(pc));

            return RequestGetText<QttResultInfo<QttMemberInfo>>("member/getMemberInfo", pc);
        }

        /// <summary>
        /// 读取文章
        /// </summary>
        /// <param name="memberId"></param>
        /// <param name="token"></param>
        /// <param name="articleKeyOrUrl">文章key或文章url</param>
        /// <returns></returns>
        public static QttResultInfo<QttReadArticleResult> ReadArticle(string memberId, string token, string articleKeyOrUrl)
        {
            string articleKey = articleKeyOrUrl;
            if (articleKey.Contains("key="))
            {
                articleKey = GetArticleKeyByUrl(articleKeyOrUrl);
            }
            var pc = CreateParam1("200");
            pc.Add("cb", "jsonp2");
            pc.Add("ua", DefaultUserAgent);
            pc.Add("member_id", memberId);
            pc.Add("key", articleKey);
            pc.Add("token", token);

            var result = RequestGetText<QttResultInfo<QttReadArticleResult>>("content/read",pc);
            result.Code = result.Data.StatusCode;
            if (result.Code != 0)
            {
                result.Message = "";
            }

            return result;
        }

        /// <summary>
        /// 从文章URL中获取key值
        /// </summary>
        /// <param name="url">文章URL</param>
        /// <returns></returns>
        public static string GetArticleKeyByUrl(string url)
        {
            var startIndex = url.IndexOf("key=") + 4;
            var endIndex = url.IndexOf("&", startIndex) - 1;

            return url.Substring(startIndex, endIndex + 1 - startIndex);
        }

        /// <summary>
        /// 开宝箱
        /// </summary>
        /// <param name="memberToken"></param>
        /// <returns>返回获取的金币</returns>
        public static int OpenTreasureBox(string memberToken)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("token", memberToken);
            pc.Add("dtu", "200");
            pc.Add("_", GetCurrentUnixTimeInMillis().ToString());

            string respStr = RequestGetText("mission/receiveTreasureBox", pc);

            var type = new
            {
                code = 0,
                message = "",
                currentTime = 0l,
                data = new
                {
                    amount=0
                },
            };

            var typeValue = JsonConvert.DeserializeAnonymousType(respStr, type);

            if (typeValue.code != 0)
                return typeValue.code;

            return typeValue.data.amount;
        }

        /// <summary>
        /// 模拟分享到微信朋友圈
        /// </summary>
        /// <param name="memberToken"></param>
        /// <returns>返回奖励金币数；如果失败，则返回错误码</returns>
        public static int ShareToWeiXin(string memberToken)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("token", memberToken);
            pc.Add("dtu", "200");
            pc.Add("_", GetCurrentUnixTimeInMillis().ToString());

            string respStr = RequestGetText("mission/shareInvite", pc);

            var type = new
            {
                code = 0,
                message = "",
                currentTime = 0l,
                data = new
                {
                    amount = 0
                },
            };

            var typeValue = JsonConvert.DeserializeAnonymousType(respStr, type);

            if (typeValue.code != 0)
                return typeValue.code;

            return typeValue.data.amount;
        }

        /// <summary>
        /// 今天是否已签到
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool IsTodaySignIn(string token)
        {
            var result = QttHelper.GetMessionList(token);

            return result.Data.SignIn.Today;
        }

        /// <summary>
        /// 签到
        /// </summary>
        /// <param name="memberToken"></param>
        /// <returns></returns>
        public static QttResultInfo<QttSignInResult> SignIn(string memberToken)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("token", memberToken);
            pc.Add("dtu", "200");
            pc.Add("_", GetCurrentUnixTimeInMillis().ToString());

            string respStr = RequestGetText("mission/signIn", pc);

            var typeValue = JsonConvert.DeserializeObject<QttResultInfo<QttSignInResult>>(respStr);

            return typeValue;
        }

        /// <summary>
        /// 获取宝箱状态信息
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static QttTreasureInfo GetTreasureInfo(string token)
        {
            var result = QttHelper.GetMessionList(token);
            var info = new QttTreasureInfo();
            if (result.Data.TreasureBox.Next != null)
            {
                var nextOpenTreasureTime = OtherUtil.UnixTimeInSeconds2DateTime(result.Data.TreasureBox.Next.Value);
                info.IsOpenTreasureAble = false;
                info.LeftTime = nextOpenTreasureTime - DateTime.Now;
            }
            else
            {
                info.IsOpenTreasureAble = true;
                info.LeftTime = TimeSpan.Zero;
            }

            return info;
        }

        /// <summary>
        /// 获取新手任务
        /// </summary>
        /// <param name="memberToken"></param>
        /// <returns></returns>
        public static QttResultInfo<QttFresherMissionInfo> GetMessionList(string memberToken)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("token", memberToken);
            pc.Add("dtu", "200");
            pc.Add("_", GetCurrentUnixTimeInMillis().ToString());

            string respStr = RequestGetText("mission/getMissionList", pc);

            var typeValue = JsonConvert.DeserializeObject<QttResultInfo<QttFresherMissionInfo>>(respStr);

            return typeValue;
        }

        /// <summary>
        /// 获取徒弟进贡
        /// </summary>
        /// <param name="memberToken"></param>
        /// <returns></returns>
        public static List<QttPupilIncomeInfo> GetPupilIncomes(string memberToken)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("token", memberToken);
            pc.Add("limit", "50");
            pc.Add("dtu", "200");
            pc.Add("_", GetCurrentUnixTimeInMillis().ToString());

            string respStr = RequestGetText("mission/pupilIncomeNew", pc);

            var type = new
            {
                code = 0,
                message = "",
                currentTime = 0l,
                data = new
                {
                    total = 0,
                    pupil = new List<QttPupilIncomeInfo>(),
                },
            };

            var typeValue = JsonConvert.DeserializeAnonymousType(respStr, type);

            return typeValue.data.pupil;
        }

        /// <summary>
        /// 获取收入信息
        /// </summary>
        /// <param name="memberToken"></param>
        /// <param name="incomeType">收入类型：balance或coins</param>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static QttResultInfo<QttIncomeInfo> GetIncomes(string memberToken, string incomeType, int pageNum, int pageSize)
        {
            Dictionary<string, object> pc = new Dictionary<string, object>();
            pc.Add("token", memberToken);
            pc.Add("type", incomeType);
            pc.Add("page", pageNum.ToString());
            pc.Add("page_size", pageSize.ToString());
            pc.Add("need_total", "1");
            pc.Add("need_detail", "1");
            pc.Add("api_version", "1");
            pc.Add("dtu", "200");
            pc.Add("_", GetCurrentUnixTimeInMillis().ToString());

            string respStr = RequestGetText("member/getMemberIncome", pc);

            var typeValue = JsonConvert.DeserializeObject<QttResultInfo<QttIncomeInfo>>(respStr);

            return typeValue;
        }

        private static string RequestPostText(string url, Dictionary<string, object> paras)
        {
            string postData = ParamDic2String(paras);
            return HttpUtil.GetResponseString(url, HttpMethod.POST, postData);
        }

        private static T RequestPostText<T>(string url, Dictionary<string, object> paras)
        {
            return JsonConvert.DeserializeObject<T>(RequestPostText(url, paras));
        }

        private static string RequestGetText(string subUrl, Dictionary<string, object> paras)
        {
            string url = string.Format("http://api.1sapp.com/{0}?{1}", subUrl, ParamDic2String(paras));
            var respStr = HttpUtil.GetResponseString(url, HttpMethod.GET, null);

            return FixJsonObjectString(respStr);
        }

        private static T RequestGetText<T>(string subUrl, Dictionary<string, object> paras)
        {
            return JsonConvert.DeserializeObject<T>(RequestGetText(subUrl, paras));
        }

        private static Image RequestGetImage(string subUrl, Dictionary<string, object> paras)
        {
            string url = string.Format("http://api.1sapp.com/{0}?{1}", subUrl, ParamDic2String(paras));

            return Image.FromStream(HttpUtil.GetResponse(url, HttpMethod.GET, null).GetResponseStream());
        }

        /// <summary>
        /// 参数列表转字符串
        /// </summary>
        /// <param name="paras"></param>
        /// <returns></returns>
        public static string ParamDic2String(Dictionary<string, object> paras)
        {
            string result = string.Empty;
            if (paras != null)
            {
                foreach (var item in paras)
                {
                    if (item.Value == null)
                    {
                        result += item.Key + "&";
                    }
                    else
                    {
                        result +=
                            string.Format("{0}={1}&", item.Key, HttpUtility.UrlEncode(item.Value.ToString()));
                    }
                }
                result = result.TrimEnd('&');
            }

            return result;
        }

        /// <summary>
        /// 根据url获取Image
        /// </summary>
        /// <param name="url">url地址</param>
        /// <returns></returns>
        public static Image GetImageByUrl(string url)
        {
            WebClient client = new WebClient();
            var data = client.DownloadData(url);

            return Image.FromStream(new MemoryStream(data));
        }

        /// <summary>
        /// 获取当前Unix时间戳，单位毫秒
        /// </summary>
        /// <returns></returns>
        public static long GetCurrentUnixTimeInMillis()
        {
            return OtherUtil.DateTime2UnixTimeInMillis(DateTime.Now);
        }

        /// <summary>
        /// 获取当前Unix时间戳，单位秒
        /// </summary>
        /// <returns></returns>
        public static long GetCurrentUnixTimeInSeconds()
        {
            return OtherUtil.DateTime2UnixTimeInMillis(DateTime.Now);
        }

        /// <summary>
        /// 根据错误码获取错误信息
        /// </summary>
        /// <param name="errorCode">错误码</param>
        /// <returns></returns>
        public static string GetErrorMessage(int errorCode)
        {
            string errorMsg = null;

            switch (errorCode)
            {
                case -1703:
                    errorMsg = "该奖励已达上限!";
                    break;
                case -1710:
                    errorMsg = "奖励活动未开始!";
                    break;
                case -132:
                    errorMsg = "今天您已经签到过了";
                    break;
                case -103:
                    errorMsg = "该号码已注册";
                    break;
                case -126:
                    errorMsg = "权限错误";
                    break;
            }

            return errorMsg;
        }

        /// <summary>
        /// 修复Json对象字符串
        /// </summary>
        /// <param name="str">未修复的Json对象字符串</param>
        /// <returns></returns>
        private static string FixJsonObjectString(string str)
        {
            var startIndex = str.IndexOf("{");
            var endIndex = str.LastIndexOf("}");

            return str.Substring(startIndex, endIndex + 1 - startIndex);
        }
    }
}
